#include <include/mmu.h>
#include <include/memlayout.h>
#include <include/trap.h>
#include <include/device.h>

###################################################################
# exceptions/interrupts
###################################################################

/* The TRAPHANDLER macro defines a globally-visible function for handling
 * a trap.  It pushes a trap number onto the stack, then jumps to _alltraps.
 * Use TRAPHANDLER for traps where the CPU automatically pushes an error code.
 */ 
#define TRAPHANDLER(name, num)						\
	.globl name;		/* define global symbol for 'name' */	\
	.type name, @function;	/* symbol type is function */		\
	.align 2;		/* align function definition */		\
	name:			/* function starts here */		\
	pushl $(num);							\
	jmp _alltraps

/* Use TRAPHANDLER_NOEC for traps where the CPU doesn't push an error code.
 * It pushes a 0 in place of the error code, so the trap frame has the same
 * format in either case.
 */
#define TRAPHANDLER_NOEC(name, num)					\
	.globl name;							\
	.type name, @function;						\
	.align 2;							\
	name:								\
	pushl $0xFFFFFFFF;							\
	pushl $(num);							\
	jmp _alltraps

.text

TRAPHANDLER_NOEC(isr0,0);
TRAPHANDLER_NOEC(isr1,1);
TRAPHANDLER_NOEC(isr2,2);
TRAPHANDLER_NOEC(isr3,3);
TRAPHANDLER_NOEC(isr4,4);
TRAPHANDLER_NOEC(isr5,5);
TRAPHANDLER_NOEC(isr6,6);
TRAPHANDLER_NOEC(isr7,7);
TRAPHANDLER(isr8,8);
TRAPHANDLER(isr9,9);
TRAPHANDLER(isr10,10);
TRAPHANDLER(isr11,11);
TRAPHANDLER(isr12,12);
TRAPHANDLER(isr13,13);
TRAPHANDLER(isr14,14);
TRAPHANDLER(isr15,15);
TRAPHANDLER_NOEC(isr16,16);
TRAPHANDLER(isr17,17);
TRAPHANDLER_NOEC(isr18,18);
TRAPHANDLER_NOEC(isr19,19);

TRAPHANDLER_NOEC(syscall_entry,48);

/* setup hardware interrupts */
TRAPHANDLER_NOEC(irq0,INT_VECTOR_IRQ0);
TRAPHANDLER_NOEC(irq1,INT_VECTOR_IRQ0+1);
TRAPHANDLER_NOEC(irq2,INT_VECTOR_IRQ0+2);
TRAPHANDLER_NOEC(irq3,INT_VECTOR_IRQ0+3);
TRAPHANDLER_NOEC(irq4,INT_VECTOR_IRQ0+4);
TRAPHANDLER_NOEC(irq5,INT_VECTOR_IRQ0+5);
TRAPHANDLER_NOEC(irq6,INT_VECTOR_IRQ0+6);
TRAPHANDLER_NOEC(irq7,INT_VECTOR_IRQ0+7);
TRAPHANDLER_NOEC(irq8,INT_VECTOR_IRQ0+8);
TRAPHANDLER_NOEC(irq9,INT_VECTOR_IRQ0+9);
TRAPHANDLER_NOEC(irq10,INT_VECTOR_IRQ0+10);
TRAPHANDLER_NOEC(irq11,INT_VECTOR_IRQ0+11);
TRAPHANDLER_NOEC(irq12,INT_VECTOR_IRQ0+12);
TRAPHANDLER_NOEC(irq13,INT_VECTOR_IRQ0+13);
TRAPHANDLER_NOEC(irq14,INT_VECTOR_IRQ0+14);

_alltraps:
	pushl %ds
	pushl %es
	pushl %fs
	pushl %gs
	pushal
	
	movw $GD_KD,%ax
	movw %ax,%ds
	movw %ax,%es
	movw %ax,%fs
	movw %ax,%gs

	pushl %esp

	call trap

	popl %esp
	popal
	popl %gs
	popl %fs
	popl %es
	popl %ds
	addl $4*2,%esp
	iret
